/** Copyright Notice:

    Copyright (C) 2011 Ivo Wingelaar

    This software is provided 'as-is', without any express or implied
    warranty.  In no event will the authors be held liable for any damages
    arising from the use of this software.

    Permission is granted to anyone to use this software for any purpose,
    including commercial applications, and to alter it and redistribute it
    freely, subject to the following restrictions:

    1.  The origin of this software must not be misrepresented; you must not
        claim that you wrote the original software. If you use this software
        in a product, an acknowledgment in the product documentation would be
        appreciated but is not required.
    2.  Altered source versions must be plainly marked as such, and must not be
        misrepresented as being the original software.
    3.  This notice may not be removed or altered from any source distribution.

    Please note that the Myth Library is based in part on the work of Nikolaus
    Gebhardt (Irrlicht Engine) and I give full credits to him, and the people who
    helped him for making available an excellent piece of code.

**/

//
// MythCryptoHashFunctionRIPEMD_C.cpp 010: implementation of the RIPEMD hash algorithms
//

#include "MythCrypto_HashFunctionRIPEMD_C.hpp"

#define ROL32(x, n) ((x << n) | (x >> (32-n)))

#define RIPEMDF(x,y,z) (x ^ y ^ z)
#define RIPEMDG(x,y,z) (z ^ (x & (y^z)))
#define RIPEMDH(x,y,z) (z ^ (x | ~y))
#define RIPEMDI(x,y,z) (y ^ (z & (x^y)))
#define RIPEMDJ(x,y,z) (x ^ (y | ~z))
#define RIPEMDSubroundA(f, a, b, c, d, x, s, k) a += f(b, c, d) + x + k; a = ROL32(a, s); // 128 and 256
#define RIPEMDSubroundB(f, a, b, c, d, e, x, s, k) a += f(b, c, d) + x + k; a = ROL32(a, s) + e; c = ROL32(c, 10); // 160 and 320

static const uint32_t RIPEMDC[10] =
{
    0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e,
    0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000
};

namespace Myth
{
namespace Crypto
{

/** constructor **/
HashFunctionRIPEMD128_C::HashFunctionRIPEMD128_C() :
    HashFunctionStub_C(16, 64)
{
    reset();
}

/** destructor **/
HashFunctionRIPEMD128_C::~HashFunctionRIPEMD128_C()
{
    //
}

/** virtual function **/
/** reset            **/
//! Resets the object, it can be used again for other data.
/// \return void
/// \param  void
void HashFunctionRIPEMD128_C::reset(void)
{
    HashFunctionStub_C::reset_b();
    mState[0] = 0x67452301;
    mState[1] = 0xefcdab89;
    mState[2] = 0x98badcfe;
    mState[3] = 0x10325476;
}

/** virtual function **/
/** transform_block  **/
//! Feeds a new block of data in the digester.
/// \return void
/// \param   uint8_t *data
///         Pointer to a piece of data of get_transform_size size.
void HashFunctionRIPEMD128_C::transform_block( uint8_t *data)
{
    uint32_t a1 = mState[0], a2 = mState[0];
    uint32_t b1 = mState[1], b2 = mState[1];
    uint32_t c1 = mState[2], c2 = mState[2];
    uint32_t d1 = mState[3], d2 = mState[3];

    RIPEMDSubroundA(RIPEMDF, a1, b1, c1, d1, ((uint32_t*)data)[ 0], 11, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, d1, a1, b1, c1, ((uint32_t*)data)[ 1], 14, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, c1, d1, a1, b1, ((uint32_t*)data)[ 2], 15, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, b1, c1, d1, a1, ((uint32_t*)data)[ 3], 12, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, a1, b1, c1, d1, ((uint32_t*)data)[ 4],  5, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, d1, a1, b1, c1, ((uint32_t*)data)[ 5],  8, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, c1, d1, a1, b1, ((uint32_t*)data)[ 6],  7, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, b1, c1, d1, a1, ((uint32_t*)data)[ 7],  9, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, a1, b1, c1, d1, ((uint32_t*)data)[ 8], 11, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, d1, a1, b1, c1, ((uint32_t*)data)[ 9], 13, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, c1, d1, a1, b1, ((uint32_t*)data)[10], 14, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, b1, c1, d1, a1, ((uint32_t*)data)[11], 15, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, a1, b1, c1, d1, ((uint32_t*)data)[12],  6, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, d1, a1, b1, c1, ((uint32_t*)data)[13],  7, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, c1, d1, a1, b1, ((uint32_t*)data)[14],  9, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, b1, c1, d1, a1, ((uint32_t*)data)[15],  8, RIPEMDC[0]);

    RIPEMDSubroundA(RIPEMDG, a1, b1, c1, d1, ((uint32_t*)data)[ 7],  7, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, d1, a1, b1, c1, ((uint32_t*)data)[ 4],  6, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, c1, d1, a1, b1, ((uint32_t*)data)[13],  8, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, b1, c1, d1, a1, ((uint32_t*)data)[ 1], 13, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, a1, b1, c1, d1, ((uint32_t*)data)[10], 11, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, d1, a1, b1, c1, ((uint32_t*)data)[ 6],  9, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, c1, d1, a1, b1, ((uint32_t*)data)[15],  7, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, b1, c1, d1, a1, ((uint32_t*)data)[ 3], 15, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, a1, b1, c1, d1, ((uint32_t*)data)[12],  7, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, d1, a1, b1, c1, ((uint32_t*)data)[ 0], 12, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, c1, d1, a1, b1, ((uint32_t*)data)[ 9], 15, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, b1, c1, d1, a1, ((uint32_t*)data)[ 5],  9, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, a1, b1, c1, d1, ((uint32_t*)data)[ 2], 11, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, d1, a1, b1, c1, ((uint32_t*)data)[14],  7, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, c1, d1, a1, b1, ((uint32_t*)data)[11], 13, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, b1, c1, d1, a1, ((uint32_t*)data)[ 8], 12, RIPEMDC[1]);

    RIPEMDSubroundA(RIPEMDH, a1, b1, c1, d1, ((uint32_t*)data)[ 3], 11, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, d1, a1, b1, c1, ((uint32_t*)data)[10], 13, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, c1, d1, a1, b1, ((uint32_t*)data)[14],  6, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, b1, c1, d1, a1, ((uint32_t*)data)[ 4],  7, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, a1, b1, c1, d1, ((uint32_t*)data)[ 9], 14, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, d1, a1, b1, c1, ((uint32_t*)data)[15],  9, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, c1, d1, a1, b1, ((uint32_t*)data)[ 8], 13, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, b1, c1, d1, a1, ((uint32_t*)data)[ 1], 15, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, a1, b1, c1, d1, ((uint32_t*)data)[ 2], 14, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, d1, a1, b1, c1, ((uint32_t*)data)[ 7],  8, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, c1, d1, a1, b1, ((uint32_t*)data)[ 0], 13, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, b1, c1, d1, a1, ((uint32_t*)data)[ 6],  6, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, a1, b1, c1, d1, ((uint32_t*)data)[13],  5, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, d1, a1, b1, c1, ((uint32_t*)data)[11], 12, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, c1, d1, a1, b1, ((uint32_t*)data)[ 5],  7, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, b1, c1, d1, a1, ((uint32_t*)data)[12],  5, RIPEMDC[2]);

    RIPEMDSubroundA(RIPEMDI, a1, b1, c1, d1, ((uint32_t*)data)[ 1], 11, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, d1, a1, b1, c1, ((uint32_t*)data)[ 9], 12, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, c1, d1, a1, b1, ((uint32_t*)data)[11], 14, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, b1, c1, d1, a1, ((uint32_t*)data)[10], 15, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, a1, b1, c1, d1, ((uint32_t*)data)[ 0], 14, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, d1, a1, b1, c1, ((uint32_t*)data)[ 8], 15, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, c1, d1, a1, b1, ((uint32_t*)data)[12],  9, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, b1, c1, d1, a1, ((uint32_t*)data)[ 4],  8, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, a1, b1, c1, d1, ((uint32_t*)data)[13],  9, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, d1, a1, b1, c1, ((uint32_t*)data)[ 3], 14, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, c1, d1, a1, b1, ((uint32_t*)data)[ 7],  5, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, b1, c1, d1, a1, ((uint32_t*)data)[15],  6, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, a1, b1, c1, d1, ((uint32_t*)data)[14],  8, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, d1, a1, b1, c1, ((uint32_t*)data)[ 5],  6, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, c1, d1, a1, b1, ((uint32_t*)data)[ 6],  5, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, b1, c1, d1, a1, ((uint32_t*)data)[ 2], 12, RIPEMDC[3]);

    RIPEMDSubroundA(RIPEMDI, a2, b2, c2, d2, ((uint32_t*)data)[ 5],  8, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, d2, a2, b2, c2, ((uint32_t*)data)[14],  9, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, c2, d2, a2, b2, ((uint32_t*)data)[ 7],  9, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, b2, c2, d2, a2, ((uint32_t*)data)[ 0], 11, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, a2, b2, c2, d2, ((uint32_t*)data)[ 9], 13, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, d2, a2, b2, c2, ((uint32_t*)data)[ 2], 15, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, c2, d2, a2, b2, ((uint32_t*)data)[11], 15, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, b2, c2, d2, a2, ((uint32_t*)data)[ 4],  5, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, a2, b2, c2, d2, ((uint32_t*)data)[13],  7, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, d2, a2, b2, c2, ((uint32_t*)data)[ 6],  7, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, c2, d2, a2, b2, ((uint32_t*)data)[15],  8, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, b2, c2, d2, a2, ((uint32_t*)data)[ 8], 11, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, a2, b2, c2, d2, ((uint32_t*)data)[ 1], 14, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, d2, a2, b2, c2, ((uint32_t*)data)[10], 14, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, c2, d2, a2, b2, ((uint32_t*)data)[ 3], 12, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, b2, c2, d2, a2, ((uint32_t*)data)[12],  6, RIPEMDC[5]);

    RIPEMDSubroundA(RIPEMDH, a2, b2, c2, d2, ((uint32_t*)data)[ 6],  9, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, d2, a2, b2, c2, ((uint32_t*)data)[11], 13, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, c2, d2, a2, b2, ((uint32_t*)data)[ 3], 15, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, b2, c2, d2, a2, ((uint32_t*)data)[ 7],  7, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, a2, b2, c2, d2, ((uint32_t*)data)[ 0], 12, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, d2, a2, b2, c2, ((uint32_t*)data)[13],  8, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, c2, d2, a2, b2, ((uint32_t*)data)[ 5],  9, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, b2, c2, d2, a2, ((uint32_t*)data)[10], 11, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, a2, b2, c2, d2, ((uint32_t*)data)[14],  7, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, d2, a2, b2, c2, ((uint32_t*)data)[15],  7, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, c2, d2, a2, b2, ((uint32_t*)data)[ 8], 12, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, b2, c2, d2, a2, ((uint32_t*)data)[12],  7, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, a2, b2, c2, d2, ((uint32_t*)data)[ 4],  6, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, d2, a2, b2, c2, ((uint32_t*)data)[ 9], 15, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, c2, d2, a2, b2, ((uint32_t*)data)[ 1], 13, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, b2, c2, d2, a2, ((uint32_t*)data)[ 2], 11, RIPEMDC[6]);

    RIPEMDSubroundA(RIPEMDG, a2, b2, c2, d2, ((uint32_t*)data)[15],  9, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, d2, a2, b2, c2, ((uint32_t*)data)[ 5],  7, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, c2, d2, a2, b2, ((uint32_t*)data)[ 1], 15, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, b2, c2, d2, a2, ((uint32_t*)data)[ 3], 11, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, a2, b2, c2, d2, ((uint32_t*)data)[ 7],  8, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, d2, a2, b2, c2, ((uint32_t*)data)[14],  6, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, c2, d2, a2, b2, ((uint32_t*)data)[ 6],  6, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, b2, c2, d2, a2, ((uint32_t*)data)[ 9], 14, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, a2, b2, c2, d2, ((uint32_t*)data)[11], 12, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, d2, a2, b2, c2, ((uint32_t*)data)[ 8], 13, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, c2, d2, a2, b2, ((uint32_t*)data)[12],  5, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, b2, c2, d2, a2, ((uint32_t*)data)[ 2], 14, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, a2, b2, c2, d2, ((uint32_t*)data)[10], 13, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, d2, a2, b2, c2, ((uint32_t*)data)[ 0], 13, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, c2, d2, a2, b2, ((uint32_t*)data)[ 4],  7, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, b2, c2, d2, a2, ((uint32_t*)data)[13],  5, RIPEMDC[7]);

    RIPEMDSubroundA(RIPEMDF, a2, b2, c2, d2, ((uint32_t*)data)[ 8], 15, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, d2, a2, b2, c2, ((uint32_t*)data)[ 6],  5, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, c2, d2, a2, b2, ((uint32_t*)data)[ 4],  8, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, b2, c2, d2, a2, ((uint32_t*)data)[ 1], 11, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, a2, b2, c2, d2, ((uint32_t*)data)[ 3], 14, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, d2, a2, b2, c2, ((uint32_t*)data)[11], 14, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, c2, d2, a2, b2, ((uint32_t*)data)[15],  6, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, b2, c2, d2, a2, ((uint32_t*)data)[ 0], 14, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, a2, b2, c2, d2, ((uint32_t*)data)[ 5],  6, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, d2, a2, b2, c2, ((uint32_t*)data)[12],  9, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, c2, d2, a2, b2, ((uint32_t*)data)[ 2], 12, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, b2, c2, d2, a2, ((uint32_t*)data)[13],  9, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, a2, b2, c2, d2, ((uint32_t*)data)[ 9], 12, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, d2, a2, b2, c2, ((uint32_t*)data)[ 7],  5, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, c2, d2, a2, b2, ((uint32_t*)data)[10], 15, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, b2, c2, d2, a2, ((uint32_t*)data)[14],  8, RIPEMDC[9]);

    c1 = mState[1] + c1 + d2;
    mState[1] = mState[2] + d1 + a2;
    mState[2] = mState[3] + a1 + b2;
    mState[3] = mState[0] + b1 + c2;
    mState[0] = c1;
}

/** virtual function **/
/** finish           **/
//! Finishes the algorithm, no data can be fed again.
/// \return void
/// \param  void
void HashFunctionRIPEMD128_C::finish(void)
{
    uint8_t padding[64];
    uint8_t len[8];
    memset(padding, 0, 64);
    padding[0] = 0x80;

    ((uint32_t*)len)[0] = get_processed() << 3;
    ((uint32_t*)len)[1] = get_processed() >> 29;

    uint32_t buffered = get_processed() & 0x3f;
    uint32_t paddingn = (buffered < 56) ? (56 - buffered) : (120 - buffered);

    feed(padding, paddingn);
    feed(len, 8);
}

/** virtual function **/
/** get_hash         **/
//! Returns the hash.
/// \return void
/// \param   uint8_t *hash
///         A pointer to a location where you want to store the hash.
void HashFunctionRIPEMD128_C::get_hash( uint8_t *hash)
{
    for(uint32_t a = 0; a < 16; a++)
        hash[a] = ((uint8_t*)mState)[a];
}

/** constructor **/
HashFunctionRIPEMD160_C::HashFunctionRIPEMD160_C() :
    HashFunctionStub_C(20, 64)
{
    reset();
}

/** destructor **/
HashFunctionRIPEMD160_C::~HashFunctionRIPEMD160_C()
{
    //
}

/** virtual function **/
/** reset            **/
//! Resets the object, it can be used again for other data.
/// \return void
/// \param  void
void HashFunctionRIPEMD160_C::reset(void)
{
    HashFunctionStub_C::reset_b();
    mState[0] = 0x67452301;
    mState[1] = 0xefcdab89;
    mState[2] = 0x98badcfe;
    mState[3] = 0x10325476;
    mState[4] = 0xc3d2e1f0;
}

/** virtual function **/
/** transform_block  **/
//! Feeds a new block of data in the digester.
/// \return void
/// \param   uint8_t *data
///         Pointer to a piece of data of get_transform_size size.
void HashFunctionRIPEMD160_C::transform_block( uint8_t *data)
{
    uint32_t a1 = mState[0], a2 = mState[0];
    uint32_t b1 = mState[1], b2 = mState[1];
    uint32_t c1 = mState[2], c2 = mState[2];
    uint32_t d1 = mState[3], d2 = mState[3];
    uint32_t e1 = mState[4], e2 = mState[4];

    RIPEMDSubroundB(RIPEMDF, a1, b1, c1, d1, e1, ((uint32_t*)data)[ 0], 11, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 1], 14, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 2], 15, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 3], 12, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, b1, c1, d1, e1, a1, ((uint32_t*)data)[ 4],  5, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, a1, b1, c1, d1, e1, ((uint32_t*)data)[ 5],  8, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 6],  7, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 7],  9, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 8], 11, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, b1, c1, d1, e1, a1, ((uint32_t*)data)[ 9], 13, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, a1, b1, c1, d1, e1, ((uint32_t*)data)[10], 14, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, e1, a1, b1, c1, d1, ((uint32_t*)data)[11], 15, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, d1, e1, a1, b1, c1, ((uint32_t*)data)[12],  6, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, c1, d1, e1, a1, b1, ((uint32_t*)data)[13],  7, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, b1, c1, d1, e1, a1, ((uint32_t*)data)[14],  9, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, a1, b1, c1, d1, e1, ((uint32_t*)data)[15],  8, RIPEMDC[0]);

    RIPEMDSubroundB(RIPEMDG, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 7],  7, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 4],  6, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, c1, d1, e1, a1, b1, ((uint32_t*)data)[13],  8, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, b1, c1, d1, e1, a1, ((uint32_t*)data)[ 1], 13, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, a1, b1, c1, d1, e1, ((uint32_t*)data)[10], 11, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 6],  9, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, d1, e1, a1, b1, c1, ((uint32_t*)data)[15],  7, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 3], 15, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, b1, c1, d1, e1, a1, ((uint32_t*)data)[12],  7, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, a1, b1, c1, d1, e1, ((uint32_t*)data)[ 0], 12, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 9], 15, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 5],  9, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 2], 11, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, b1, c1, d1, e1, a1, ((uint32_t*)data)[14],  7, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, a1, b1, c1, d1, e1, ((uint32_t*)data)[11], 13, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 8], 12, RIPEMDC[1]);

    RIPEMDSubroundB(RIPEMDH, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 3], 11, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, c1, d1, e1, a1, b1, ((uint32_t*)data)[10], 13, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, b1, c1, d1, e1, a1, ((uint32_t*)data)[14],  6, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, a1, b1, c1, d1, e1, ((uint32_t*)data)[ 4],  7, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 9], 14, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, d1, e1, a1, b1, c1, ((uint32_t*)data)[15],  9, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 8], 13, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, b1, c1, d1, e1, a1, ((uint32_t*)data)[ 1], 15, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, a1, b1, c1, d1, e1, ((uint32_t*)data)[ 2], 14, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 7],  8, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 0], 13, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 6],  6, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, b1, c1, d1, e1, a1, ((uint32_t*)data)[13],  5, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, a1, b1, c1, d1, e1, ((uint32_t*)data)[11], 12, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 5],  7, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, d1, e1, a1, b1, c1, ((uint32_t*)data)[12],  5, RIPEMDC[2]);

    RIPEMDSubroundB(RIPEMDI, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 1], 11, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, b1, c1, d1, e1, a1, ((uint32_t*)data)[ 9], 12, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, a1, b1, c1, d1, e1, ((uint32_t*)data)[11], 14, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, e1, a1, b1, c1, d1, ((uint32_t*)data)[10], 15, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 0], 14, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 8], 15, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, b1, c1, d1, e1, a1, ((uint32_t*)data)[12],  9, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, a1, b1, c1, d1, e1, ((uint32_t*)data)[ 4],  8, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, e1, a1, b1, c1, d1, ((uint32_t*)data)[13],  9, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 3], 14, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 7],  5, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, b1, c1, d1, e1, a1, ((uint32_t*)data)[15],  6, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, a1, b1, c1, d1, e1, ((uint32_t*)data)[14],  8, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 5],  6, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 6],  5, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 2], 12, RIPEMDC[3]);

    RIPEMDSubroundB(RIPEMDJ, b1, c1, d1, e1, a1, ((uint32_t*)data)[ 4],  9, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, a1, b1, c1, d1, e1, ((uint32_t*)data)[ 0], 15, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 5],  5, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 9], 11, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 7],  6, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, b1, c1, d1, e1, a1, ((uint32_t*)data)[12],  8, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, a1, b1, c1, d1, e1, ((uint32_t*)data)[ 2], 13, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, e1, a1, b1, c1, d1, ((uint32_t*)data)[10], 12, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, d1, e1, a1, b1, c1, ((uint32_t*)data)[14],  5, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 1], 12, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, b1, c1, d1, e1, a1, ((uint32_t*)data)[ 3], 13, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, a1, b1, c1, d1, e1, ((uint32_t*)data)[ 8], 14, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, e1, a1, b1, c1, d1, ((uint32_t*)data)[11], 11, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 6],  8, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, c1, d1, e1, a1, b1, ((uint32_t*)data)[15],  5, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, b1, c1, d1, e1, a1, ((uint32_t*)data)[13],  6, RIPEMDC[4]);

    RIPEMDSubroundB(RIPEMDJ, a2, b2, c2, d2, e2, ((uint32_t*)data)[ 5],  8, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, e2, a2, b2, c2, d2, ((uint32_t*)data)[14],  9, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, d2, e2, a2, b2, c2, ((uint32_t*)data)[ 7],  9, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 0], 11, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, b2, c2, d2, e2, a2, ((uint32_t*)data)[ 9], 13, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, a2, b2, c2, d2, e2, ((uint32_t*)data)[ 2], 15, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, e2, a2, b2, c2, d2, ((uint32_t*)data)[11], 15, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, d2, e2, a2, b2, c2, ((uint32_t*)data)[ 4],  5, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, c2, d2, e2, a2, b2, ((uint32_t*)data)[13],  7, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, b2, c2, d2, e2, a2, ((uint32_t*)data)[ 6],  7, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, a2, b2, c2, d2, e2, ((uint32_t*)data)[15],  8, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 8], 11, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, d2, e2, a2, b2, c2, ((uint32_t*)data)[ 1], 14, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, c2, d2, e2, a2, b2, ((uint32_t*)data)[10], 14, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, b2, c2, d2, e2, a2, ((uint32_t*)data)[ 3], 12, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, a2, b2, c2, d2, e2, ((uint32_t*)data)[12],  6, RIPEMDC[5]);

    RIPEMDSubroundB(RIPEMDI, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 6],  9, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, d2, e2, a2, b2, c2, ((uint32_t*)data)[11], 13, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 3], 15, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, b2, c2, d2, e2, a2, ((uint32_t*)data)[ 7],  7, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, a2, b2, c2, d2, e2, ((uint32_t*)data)[ 0], 12, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, e2, a2, b2, c2, d2, ((uint32_t*)data)[13],  8, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, d2, e2, a2, b2, c2, ((uint32_t*)data)[ 5],  9, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, c2, d2, e2, a2, b2, ((uint32_t*)data)[10], 11, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, b2, c2, d2, e2, a2, ((uint32_t*)data)[14],  7, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, a2, b2, c2, d2, e2, ((uint32_t*)data)[15],  7, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 8], 12, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, d2, e2, a2, b2, c2, ((uint32_t*)data)[12],  7, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 4],  6, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, b2, c2, d2, e2, a2, ((uint32_t*)data)[ 9], 15, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, a2, b2, c2, d2, e2, ((uint32_t*)data)[ 1], 13, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 2], 11, RIPEMDC[6]);

    RIPEMDSubroundB(RIPEMDH, d2, e2, a2, b2, c2, ((uint32_t*)data)[15],  9, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 5],  7, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, b2, c2, d2, e2, a2, ((uint32_t*)data)[ 1], 15, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, a2, b2, c2, d2, e2, ((uint32_t*)data)[ 3], 11, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 7],  8, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, d2, e2, a2, b2, c2, ((uint32_t*)data)[14],  6, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 6],  6, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, b2, c2, d2, e2, a2, ((uint32_t*)data)[ 9], 14, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, a2, b2, c2, d2, e2, ((uint32_t*)data)[11], 12, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 8], 13, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, d2, e2, a2, b2, c2, ((uint32_t*)data)[12],  5, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 2], 14, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, b2, c2, d2, e2, a2, ((uint32_t*)data)[10], 13, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, a2, b2, c2, d2, e2, ((uint32_t*)data)[ 0], 13, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 4],  7, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, d2, e2, a2, b2, c2, ((uint32_t*)data)[13],  5, RIPEMDC[7]);

    RIPEMDSubroundB(RIPEMDG, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 8], 15, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, b2, c2, d2, e2, a2, ((uint32_t*)data)[ 6],  5, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, a2, b2, c2, d2, e2, ((uint32_t*)data)[ 4],  8, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 1], 11, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, d2, e2, a2, b2, c2, ((uint32_t*)data)[ 3], 14, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, c2, d2, e2, a2, b2, ((uint32_t*)data)[11], 14, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, b2, c2, d2, e2, a2, ((uint32_t*)data)[15],  6, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, a2, b2, c2, d2, e2, ((uint32_t*)data)[ 0], 14, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 5],  6, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, d2, e2, a2, b2, c2, ((uint32_t*)data)[12],  9, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 2], 12, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, b2, c2, d2, e2, a2, ((uint32_t*)data)[13],  9, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, a2, b2, c2, d2, e2, ((uint32_t*)data)[ 9], 12, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 7],  5, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, d2, e2, a2, b2, c2, ((uint32_t*)data)[10], 15, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, c2, d2, e2, a2, b2, ((uint32_t*)data)[14],  8, RIPEMDC[8]);

    RIPEMDSubroundB(RIPEMDF, b2, c2, d2, e2, a2, ((uint32_t*)data)[12],  8, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, a2, b2, c2, d2, e2, ((uint32_t*)data)[15],  5, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, e2, a2, b2, c2, d2, ((uint32_t*)data)[10], 12, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, d2, e2, a2, b2, c2, ((uint32_t*)data)[ 4],  9, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 1], 12, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, b2, c2, d2, e2, a2, ((uint32_t*)data)[ 5],  5, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, a2, b2, c2, d2, e2, ((uint32_t*)data)[ 8], 14, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 7],  6, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, d2, e2, a2, b2, c2, ((uint32_t*)data)[ 6],  8, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 2], 13, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, b2, c2, d2, e2, a2, ((uint32_t*)data)[13],  6, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, a2, b2, c2, d2, e2, ((uint32_t*)data)[14],  5, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 0], 15, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, d2, e2, a2, b2, c2, ((uint32_t*)data)[ 3], 13, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 9], 11, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, b2, c2, d2, e2, a2, ((uint32_t*)data)[11], 11, RIPEMDC[9]);

    c1 = mState[1] + c1 + d2;
    mState[1] = mState[2] + d1 + e2;
    mState[2] = mState[3] + e1 + a2;
    mState[3] = mState[4] + a1 + b2;
    mState[4] = mState[0] + b1 + c2;
    mState[0] = c1;
}

/** virtual function **/
/** finish           **/
//! Finishes the algorithm, no data can be fed again.
/// \return void
/// \param  void
void HashFunctionRIPEMD160_C::finish(void)
{
    uint8_t padding[64];
    uint8_t len[8];
    memset(padding, 0, 64);
    padding[0] = 0x80;

    ((uint32_t*)len)[0] = get_processed() << 3;
    ((uint32_t*)len)[1] = get_processed() >> 29;

    uint32_t buffered = get_processed() & 0x3f;
    uint32_t paddingn = (buffered < 56) ? (56 - buffered) : (120 - buffered);

    feed(padding, paddingn);
    feed(len, 8);
}

/** virtual function **/
/** get_hash         **/
//! Returns the hash.
/// \return void
/// \param   uint8_t *hash
///         A pointer to a location where you want to store the hash.
void HashFunctionRIPEMD160_C::get_hash( uint8_t *hash)
{
    for(uint32_t a = 0; a < 20; a++)
        hash[a] = ((uint8_t*)mState)[a];
}

/** constructor **/
HashFunctionRIPEMD256_C::HashFunctionRIPEMD256_C() :
    HashFunctionStub_C(32, 64)
{
    reset();
}

/** destructor **/
HashFunctionRIPEMD256_C::~HashFunctionRIPEMD256_C()
{
    //
}

/** virtual function **/
/** reset            **/
//! Resets the object, it can be used again for other data.
/// \return void
/// \param  void
void HashFunctionRIPEMD256_C::reset(void)
{
    HashFunctionStub_C::reset_b();
    mState[0] = 0x67452301;
    mState[1] = 0xefcdab89;
    mState[2] = 0x98badcfe;
    mState[3] = 0x10325476;
    mState[4] = 0x76543210;
    mState[5] = 0xfedcba98;
    mState[6] = 0x89abcdef;
    mState[7] = 0x01234567;
}

/** virtual function **/
/** transform_block  **/
//! Feeds a new block of data in the digester.
/// \return void
/// \param   uint8_t *data
///         Pointer to a piece of data of get_transform_size size.
void HashFunctionRIPEMD256_C::transform_block( uint8_t *data)
{
    uint32_t a1 = mState[0];
    uint32_t b1 = mState[1];
    uint32_t c1 = mState[2];
    uint32_t d1 = mState[3];
    uint32_t a2 = mState[4];
    uint32_t b2 = mState[5];
    uint32_t c2 = mState[6];
    uint32_t d2 = mState[7];

    RIPEMDSubroundA(RIPEMDF, a1, b1, c1, d1, ((uint32_t*)data)[ 0], 11, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, d1, a1, b1, c1, ((uint32_t*)data)[ 1], 14, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, c1, d1, a1, b1, ((uint32_t*)data)[ 2], 15, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, b1, c1, d1, a1, ((uint32_t*)data)[ 3], 12, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, a1, b1, c1, d1, ((uint32_t*)data)[ 4],  5, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, d1, a1, b1, c1, ((uint32_t*)data)[ 5],  8, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, c1, d1, a1, b1, ((uint32_t*)data)[ 6],  7, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, b1, c1, d1, a1, ((uint32_t*)data)[ 7],  9, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, a1, b1, c1, d1, ((uint32_t*)data)[ 8], 11, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, d1, a1, b1, c1, ((uint32_t*)data)[ 9], 13, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, c1, d1, a1, b1, ((uint32_t*)data)[10], 14, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, b1, c1, d1, a1, ((uint32_t*)data)[11], 15, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, a1, b1, c1, d1, ((uint32_t*)data)[12],  6, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, d1, a1, b1, c1, ((uint32_t*)data)[13],  7, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, c1, d1, a1, b1, ((uint32_t*)data)[14],  9, RIPEMDC[0]);
    RIPEMDSubroundA(RIPEMDF, b1, c1, d1, a1, ((uint32_t*)data)[15],  8, RIPEMDC[0]);

    RIPEMDSubroundA(RIPEMDI, a2, b2, c2, d2, ((uint32_t*)data)[ 5],  8, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, d2, a2, b2, c2, ((uint32_t*)data)[14],  9, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, c2, d2, a2, b2, ((uint32_t*)data)[ 7],  9, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, b2, c2, d2, a2, ((uint32_t*)data)[ 0], 11, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, a2, b2, c2, d2, ((uint32_t*)data)[ 9], 13, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, d2, a2, b2, c2, ((uint32_t*)data)[ 2], 15, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, c2, d2, a2, b2, ((uint32_t*)data)[11], 15, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, b2, c2, d2, a2, ((uint32_t*)data)[ 4],  5, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, a2, b2, c2, d2, ((uint32_t*)data)[13],  7, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, d2, a2, b2, c2, ((uint32_t*)data)[ 6],  7, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, c2, d2, a2, b2, ((uint32_t*)data)[15],  8, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, b2, c2, d2, a2, ((uint32_t*)data)[ 8], 11, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, a2, b2, c2, d2, ((uint32_t*)data)[ 1], 14, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, d2, a2, b2, c2, ((uint32_t*)data)[10], 14, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, c2, d2, a2, b2, ((uint32_t*)data)[ 3], 12, RIPEMDC[5]);
    RIPEMDSubroundA(RIPEMDI, b2, c2, d2, a2, ((uint32_t*)data)[12],  6, RIPEMDC[5]);

    Math::swap(a1, a2);

    RIPEMDSubroundA(RIPEMDG, a1, b1, c1, d1, ((uint32_t*)data)[ 7],  7, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, d1, a1, b1, c1, ((uint32_t*)data)[ 4],  6, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, c1, d1, a1, b1, ((uint32_t*)data)[13],  8, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, b1, c1, d1, a1, ((uint32_t*)data)[ 1], 13, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, a1, b1, c1, d1, ((uint32_t*)data)[10], 11, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, d1, a1, b1, c1, ((uint32_t*)data)[ 6],  9, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, c1, d1, a1, b1, ((uint32_t*)data)[15],  7, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, b1, c1, d1, a1, ((uint32_t*)data)[ 3], 15, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, a1, b1, c1, d1, ((uint32_t*)data)[12],  7, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, d1, a1, b1, c1, ((uint32_t*)data)[ 0], 12, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, c1, d1, a1, b1, ((uint32_t*)data)[ 9], 15, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, b1, c1, d1, a1, ((uint32_t*)data)[ 5],  9, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, a1, b1, c1, d1, ((uint32_t*)data)[ 2], 11, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, d1, a1, b1, c1, ((uint32_t*)data)[14],  7, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, c1, d1, a1, b1, ((uint32_t*)data)[11], 13, RIPEMDC[1]);
    RIPEMDSubroundA(RIPEMDG, b1, c1, d1, a1, ((uint32_t*)data)[ 8], 12, RIPEMDC[1]);

    RIPEMDSubroundA(RIPEMDH, a2, b2, c2, d2, ((uint32_t*)data)[ 6],  9, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, d2, a2, b2, c2, ((uint32_t*)data)[11], 13, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, c2, d2, a2, b2, ((uint32_t*)data)[ 3], 15, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, b2, c2, d2, a2, ((uint32_t*)data)[ 7],  7, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, a2, b2, c2, d2, ((uint32_t*)data)[ 0], 12, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, d2, a2, b2, c2, ((uint32_t*)data)[13],  8, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, c2, d2, a2, b2, ((uint32_t*)data)[ 5],  9, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, b2, c2, d2, a2, ((uint32_t*)data)[10], 11, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, a2, b2, c2, d2, ((uint32_t*)data)[14],  7, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, d2, a2, b2, c2, ((uint32_t*)data)[15],  7, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, c2, d2, a2, b2, ((uint32_t*)data)[ 8], 12, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, b2, c2, d2, a2, ((uint32_t*)data)[12],  7, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, a2, b2, c2, d2, ((uint32_t*)data)[ 4],  6, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, d2, a2, b2, c2, ((uint32_t*)data)[ 9], 15, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, c2, d2, a2, b2, ((uint32_t*)data)[ 1], 13, RIPEMDC[6]);
    RIPEMDSubroundA(RIPEMDH, b2, c2, d2, a2, ((uint32_t*)data)[ 2], 11, RIPEMDC[6]);

    Math::swap(b1, b2);

    RIPEMDSubroundA(RIPEMDH, a1, b1, c1, d1, ((uint32_t*)data)[ 3], 11, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, d1, a1, b1, c1, ((uint32_t*)data)[10], 13, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, c1, d1, a1, b1, ((uint32_t*)data)[14],  6, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, b1, c1, d1, a1, ((uint32_t*)data)[ 4],  7, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, a1, b1, c1, d1, ((uint32_t*)data)[ 9], 14, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, d1, a1, b1, c1, ((uint32_t*)data)[15],  9, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, c1, d1, a1, b1, ((uint32_t*)data)[ 8], 13, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, b1, c1, d1, a1, ((uint32_t*)data)[ 1], 15, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, a1, b1, c1, d1, ((uint32_t*)data)[ 2], 14, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, d1, a1, b1, c1, ((uint32_t*)data)[ 7],  8, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, c1, d1, a1, b1, ((uint32_t*)data)[ 0], 13, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, b1, c1, d1, a1, ((uint32_t*)data)[ 6],  6, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, a1, b1, c1, d1, ((uint32_t*)data)[13],  5, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, d1, a1, b1, c1, ((uint32_t*)data)[11], 12, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, c1, d1, a1, b1, ((uint32_t*)data)[ 5],  7, RIPEMDC[2]);
    RIPEMDSubroundA(RIPEMDH, b1, c1, d1, a1, ((uint32_t*)data)[12],  5, RIPEMDC[2]);

    RIPEMDSubroundA(RIPEMDG, a2, b2, c2, d2, ((uint32_t*)data)[15],  9, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, d2, a2, b2, c2, ((uint32_t*)data)[ 5],  7, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, c2, d2, a2, b2, ((uint32_t*)data)[ 1], 15, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, b2, c2, d2, a2, ((uint32_t*)data)[ 3], 11, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, a2, b2, c2, d2, ((uint32_t*)data)[ 7],  8, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, d2, a2, b2, c2, ((uint32_t*)data)[14],  6, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, c2, d2, a2, b2, ((uint32_t*)data)[ 6],  6, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, b2, c2, d2, a2, ((uint32_t*)data)[ 9], 14, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, a2, b2, c2, d2, ((uint32_t*)data)[11], 12, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, d2, a2, b2, c2, ((uint32_t*)data)[ 8], 13, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, c2, d2, a2, b2, ((uint32_t*)data)[12],  5, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, b2, c2, d2, a2, ((uint32_t*)data)[ 2], 14, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, a2, b2, c2, d2, ((uint32_t*)data)[10], 13, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, d2, a2, b2, c2, ((uint32_t*)data)[ 0], 13, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, c2, d2, a2, b2, ((uint32_t*)data)[ 4],  7, RIPEMDC[7]);
    RIPEMDSubroundA(RIPEMDG, b2, c2, d2, a2, ((uint32_t*)data)[13],  5, RIPEMDC[7]);

    Math::swap(c1, c2);

    RIPEMDSubroundA(RIPEMDI, a1, b1, c1, d1, ((uint32_t*)data)[ 1], 11, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, d1, a1, b1, c1, ((uint32_t*)data)[ 9], 12, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, c1, d1, a1, b1, ((uint32_t*)data)[11], 14, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, b1, c1, d1, a1, ((uint32_t*)data)[10], 15, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, a1, b1, c1, d1, ((uint32_t*)data)[ 0], 14, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, d1, a1, b1, c1, ((uint32_t*)data)[ 8], 15, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, c1, d1, a1, b1, ((uint32_t*)data)[12],  9, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, b1, c1, d1, a1, ((uint32_t*)data)[ 4],  8, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, a1, b1, c1, d1, ((uint32_t*)data)[13],  9, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, d1, a1, b1, c1, ((uint32_t*)data)[ 3], 14, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, c1, d1, a1, b1, ((uint32_t*)data)[ 7],  5, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, b1, c1, d1, a1, ((uint32_t*)data)[15],  6, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, a1, b1, c1, d1, ((uint32_t*)data)[14],  8, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, d1, a1, b1, c1, ((uint32_t*)data)[ 5],  6, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, c1, d1, a1, b1, ((uint32_t*)data)[ 6],  5, RIPEMDC[3]);
    RIPEMDSubroundA(RIPEMDI, b1, c1, d1, a1, ((uint32_t*)data)[ 2], 12, RIPEMDC[3]);

    RIPEMDSubroundA(RIPEMDF, a2, b2, c2, d2, ((uint32_t*)data)[ 8], 15, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, d2, a2, b2, c2, ((uint32_t*)data)[ 6],  5, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, c2, d2, a2, b2, ((uint32_t*)data)[ 4],  8, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, b2, c2, d2, a2, ((uint32_t*)data)[ 1], 11, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, a2, b2, c2, d2, ((uint32_t*)data)[ 3], 14, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, d2, a2, b2, c2, ((uint32_t*)data)[11], 14, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, c2, d2, a2, b2, ((uint32_t*)data)[15],  6, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, b2, c2, d2, a2, ((uint32_t*)data)[ 0], 14, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, a2, b2, c2, d2, ((uint32_t*)data)[ 5],  6, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, d2, a2, b2, c2, ((uint32_t*)data)[12],  9, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, c2, d2, a2, b2, ((uint32_t*)data)[ 2], 12, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, b2, c2, d2, a2, ((uint32_t*)data)[13],  9, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, a2, b2, c2, d2, ((uint32_t*)data)[ 9], 12, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, d2, a2, b2, c2, ((uint32_t*)data)[ 7],  5, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, c2, d2, a2, b2, ((uint32_t*)data)[10], 15, RIPEMDC[9]);
    RIPEMDSubroundA(RIPEMDF, b2, c2, d2, a2, ((uint32_t*)data)[14],  8, RIPEMDC[9]);

    Math::swap(d1, d2);

    mState[0] += a1;
    mState[1] += b1;
    mState[2] += c1;
    mState[3] += d1;
    mState[4] += a2;
    mState[5] += b2;
    mState[6] += c2;
    mState[7] += d2;
}

/** virtual function **/
/** finish           **/
//! Finishes the algorithm, no data can be fed again.
/// \return void
/// \param  void
void HashFunctionRIPEMD256_C::finish(void)
{
    uint8_t padding[64];
    uint8_t len[8];
    memset(padding, 0, 64);
    padding[0] = 0x80;

    ((uint32_t*)len)[0] = get_processed() << 3;
    ((uint32_t*)len)[1] = get_processed() >> 29;

    uint32_t buffered = get_processed() & 0x3f;
    uint32_t paddingn = (buffered < 56) ? (56 - buffered) : (120 - buffered);

    feed(padding, paddingn);
    feed(len, 8);
}

/** virtual function **/
/** get_hash         **/
//! Returns the hash.
/// \return void
/// \param   uint8_t *hash
///         A pointer to a location where you want to store the hash.
void HashFunctionRIPEMD256_C::get_hash( uint8_t *hash)
{
    for(uint32_t a = 0; a < 32; a++)
        hash[a] = ((uint8_t*)mState)[a];
}

/** constructor **/
HashFunctionRIPEMD320_C::HashFunctionRIPEMD320_C() :
    HashFunctionStub_C(40, 64)
{
    reset();
}

/** destructor **/
HashFunctionRIPEMD320_C::~HashFunctionRIPEMD320_C()
{
    //
}

/** virtual function **/
/** reset            **/
//! Resets the object, it can be used again for other data.
/// \return void
/// \param  void
void HashFunctionRIPEMD320_C::reset(void)
{
    HashFunctionStub_C::reset_b();
    mState[0] = 0x67452301;
    mState[1] = 0xefcdab89;
    mState[2] = 0x98badcfe;
    mState[3] = 0x10325476;
    mState[4] = 0xc3d2e1f0;
    mState[5] = 0x76543210;
    mState[6] = 0xfedcba98;
    mState[7] = 0x89abcdef;
    mState[8] = 0x01234567;
    mState[9] = 0x3c2d1e0f;
}

/** virtual function **/
/** transform_block  **/
//! Feeds a new block of data in the digester.
/// \return void
/// \param   uint8_t *data
///         Pointer to a piece of data of get_transform_size size.
void HashFunctionRIPEMD320_C::transform_block( uint8_t *data)
{
    uint32_t a1 = mState[0];
    uint32_t b1 = mState[1];
    uint32_t c1 = mState[2];
    uint32_t d1 = mState[3];
    uint32_t e1 = mState[4];
    uint32_t a2 = mState[5];
    uint32_t b2 = mState[6];
    uint32_t c2 = mState[7];
    uint32_t d2 = mState[8];
    uint32_t e2 = mState[9];

    RIPEMDSubroundB(RIPEMDF, a1, b1, c1, d1, e1, ((uint32_t*)data)[ 0], 11, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 1], 14, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 2], 15, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 3], 12, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, b1, c1, d1, e1, a1, ((uint32_t*)data)[ 4],  5, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, a1, b1, c1, d1, e1, ((uint32_t*)data)[ 5],  8, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 6],  7, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 7],  9, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 8], 11, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, b1, c1, d1, e1, a1, ((uint32_t*)data)[ 9], 13, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, a1, b1, c1, d1, e1, ((uint32_t*)data)[10], 14, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, e1, a1, b1, c1, d1, ((uint32_t*)data)[11], 15, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, d1, e1, a1, b1, c1, ((uint32_t*)data)[12],  6, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, c1, d1, e1, a1, b1, ((uint32_t*)data)[13],  7, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, b1, c1, d1, e1, a1, ((uint32_t*)data)[14],  9, RIPEMDC[0]);
    RIPEMDSubroundB(RIPEMDF, a1, b1, c1, d1, e1, ((uint32_t*)data)[15],  8, RIPEMDC[0]);

    RIPEMDSubroundB(RIPEMDJ, a2, b2, c2, d2, e2, ((uint32_t*)data)[ 5],  8, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, e2, a2, b2, c2, d2, ((uint32_t*)data)[14],  9, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, d2, e2, a2, b2, c2, ((uint32_t*)data)[ 7],  9, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 0], 11, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, b2, c2, d2, e2, a2, ((uint32_t*)data)[ 9], 13, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, a2, b2, c2, d2, e2, ((uint32_t*)data)[ 2], 15, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, e2, a2, b2, c2, d2, ((uint32_t*)data)[11], 15, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, d2, e2, a2, b2, c2, ((uint32_t*)data)[ 4],  5, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, c2, d2, e2, a2, b2, ((uint32_t*)data)[13],  7, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, b2, c2, d2, e2, a2, ((uint32_t*)data)[ 6],  7, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, a2, b2, c2, d2, e2, ((uint32_t*)data)[15],  8, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 8], 11, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, d2, e2, a2, b2, c2, ((uint32_t*)data)[ 1], 14, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, c2, d2, e2, a2, b2, ((uint32_t*)data)[10], 14, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, b2, c2, d2, e2, a2, ((uint32_t*)data)[ 3], 12, RIPEMDC[5]);
    RIPEMDSubroundB(RIPEMDJ, a2, b2, c2, d2, e2, ((uint32_t*)data)[12],  6, RIPEMDC[5]);

    Math::swap(a1, a2);

    RIPEMDSubroundB(RIPEMDG, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 7],  7, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 4],  6, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, c1, d1, e1, a1, b1, ((uint32_t*)data)[13],  8, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, b1, c1, d1, e1, a1, ((uint32_t*)data)[ 1], 13, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, a1, b1, c1, d1, e1, ((uint32_t*)data)[10], 11, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 6],  9, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, d1, e1, a1, b1, c1, ((uint32_t*)data)[15],  7, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 3], 15, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, b1, c1, d1, e1, a1, ((uint32_t*)data)[12],  7, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, a1, b1, c1, d1, e1, ((uint32_t*)data)[ 0], 12, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 9], 15, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 5],  9, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 2], 11, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, b1, c1, d1, e1, a1, ((uint32_t*)data)[14],  7, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, a1, b1, c1, d1, e1, ((uint32_t*)data)[11], 13, RIPEMDC[1]);
    RIPEMDSubroundB(RIPEMDG, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 8], 12, RIPEMDC[1]);

    RIPEMDSubroundB(RIPEMDI, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 6],  9, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, d2, e2, a2, b2, c2, ((uint32_t*)data)[11], 13, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 3], 15, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, b2, c2, d2, e2, a2, ((uint32_t*)data)[ 7],  7, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, a2, b2, c2, d2, e2, ((uint32_t*)data)[ 0], 12, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, e2, a2, b2, c2, d2, ((uint32_t*)data)[13],  8, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, d2, e2, a2, b2, c2, ((uint32_t*)data)[ 5],  9, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, c2, d2, e2, a2, b2, ((uint32_t*)data)[10], 11, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, b2, c2, d2, e2, a2, ((uint32_t*)data)[14],  7, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, a2, b2, c2, d2, e2, ((uint32_t*)data)[15],  7, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 8], 12, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, d2, e2, a2, b2, c2, ((uint32_t*)data)[12],  7, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 4],  6, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, b2, c2, d2, e2, a2, ((uint32_t*)data)[ 9], 15, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, a2, b2, c2, d2, e2, ((uint32_t*)data)[ 1], 13, RIPEMDC[6]);
    RIPEMDSubroundB(RIPEMDI, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 2], 11, RIPEMDC[6]);

    Math::swap(b1, b2);

    RIPEMDSubroundB(RIPEMDH, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 3], 11, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, c1, d1, e1, a1, b1, ((uint32_t*)data)[10], 13, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, b1, c1, d1, e1, a1, ((uint32_t*)data)[14],  6, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, a1, b1, c1, d1, e1, ((uint32_t*)data)[ 4],  7, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 9], 14, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, d1, e1, a1, b1, c1, ((uint32_t*)data)[15],  9, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 8], 13, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, b1, c1, d1, e1, a1, ((uint32_t*)data)[ 1], 15, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, a1, b1, c1, d1, e1, ((uint32_t*)data)[ 2], 14, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 7],  8, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 0], 13, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 6],  6, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, b1, c1, d1, e1, a1, ((uint32_t*)data)[13],  5, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, a1, b1, c1, d1, e1, ((uint32_t*)data)[11], 12, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 5],  7, RIPEMDC[2]);
    RIPEMDSubroundB(RIPEMDH, d1, e1, a1, b1, c1, ((uint32_t*)data)[12],  5, RIPEMDC[2]);

    RIPEMDSubroundB(RIPEMDH, d2, e2, a2, b2, c2, ((uint32_t*)data)[15],  9, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 5],  7, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, b2, c2, d2, e2, a2, ((uint32_t*)data)[ 1], 15, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, a2, b2, c2, d2, e2, ((uint32_t*)data)[ 3], 11, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 7],  8, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, d2, e2, a2, b2, c2, ((uint32_t*)data)[14],  6, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 6],  6, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, b2, c2, d2, e2, a2, ((uint32_t*)data)[ 9], 14, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, a2, b2, c2, d2, e2, ((uint32_t*)data)[11], 12, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 8], 13, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, d2, e2, a2, b2, c2, ((uint32_t*)data)[12],  5, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 2], 14, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, b2, c2, d2, e2, a2, ((uint32_t*)data)[10], 13, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, a2, b2, c2, d2, e2, ((uint32_t*)data)[ 0], 13, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 4],  7, RIPEMDC[7]);
    RIPEMDSubroundB(RIPEMDH, d2, e2, a2, b2, c2, ((uint32_t*)data)[13],  5, RIPEMDC[7]);

    Math::swap(c1, c2);

    RIPEMDSubroundB(RIPEMDI, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 1], 11, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, b1, c1, d1, e1, a1, ((uint32_t*)data)[ 9], 12, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, a1, b1, c1, d1, e1, ((uint32_t*)data)[11], 14, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, e1, a1, b1, c1, d1, ((uint32_t*)data)[10], 15, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 0], 14, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 8], 15, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, b1, c1, d1, e1, a1, ((uint32_t*)data)[12],  9, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, a1, b1, c1, d1, e1, ((uint32_t*)data)[ 4],  8, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, e1, a1, b1, c1, d1, ((uint32_t*)data)[13],  9, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 3], 14, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 7],  5, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, b1, c1, d1, e1, a1, ((uint32_t*)data)[15],  6, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, a1, b1, c1, d1, e1, ((uint32_t*)data)[14],  8, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 5],  6, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 6],  5, RIPEMDC[3]);
    RIPEMDSubroundB(RIPEMDI, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 2], 12, RIPEMDC[3]);

    RIPEMDSubroundB(RIPEMDG, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 8], 15, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, b2, c2, d2, e2, a2, ((uint32_t*)data)[ 6],  5, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, a2, b2, c2, d2, e2, ((uint32_t*)data)[ 4],  8, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 1], 11, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, d2, e2, a2, b2, c2, ((uint32_t*)data)[ 3], 14, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, c2, d2, e2, a2, b2, ((uint32_t*)data)[11], 14, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, b2, c2, d2, e2, a2, ((uint32_t*)data)[15],  6, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, a2, b2, c2, d2, e2, ((uint32_t*)data)[ 0], 14, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 5],  6, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, d2, e2, a2, b2, c2, ((uint32_t*)data)[12],  9, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 2], 12, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, b2, c2, d2, e2, a2, ((uint32_t*)data)[13],  9, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, a2, b2, c2, d2, e2, ((uint32_t*)data)[ 9], 12, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 7],  5, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, d2, e2, a2, b2, c2, ((uint32_t*)data)[10], 15, RIPEMDC[8]);
    RIPEMDSubroundB(RIPEMDG, c2, d2, e2, a2, b2, ((uint32_t*)data)[14],  8, RIPEMDC[8]);

    Math::swap(d1, d2);

    RIPEMDSubroundB(RIPEMDJ, b1, c1, d1, e1, a1, ((uint32_t*)data)[ 4],  9, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, a1, b1, c1, d1, e1, ((uint32_t*)data)[ 0], 15, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, e1, a1, b1, c1, d1, ((uint32_t*)data)[ 5],  5, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 9], 11, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 7],  6, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, b1, c1, d1, e1, a1, ((uint32_t*)data)[12],  8, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, a1, b1, c1, d1, e1, ((uint32_t*)data)[ 2], 13, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, e1, a1, b1, c1, d1, ((uint32_t*)data)[10], 12, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, d1, e1, a1, b1, c1, ((uint32_t*)data)[14],  5, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, c1, d1, e1, a1, b1, ((uint32_t*)data)[ 1], 12, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, b1, c1, d1, e1, a1, ((uint32_t*)data)[ 3], 13, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, a1, b1, c1, d1, e1, ((uint32_t*)data)[ 8], 14, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, e1, a1, b1, c1, d1, ((uint32_t*)data)[11], 11, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, d1, e1, a1, b1, c1, ((uint32_t*)data)[ 6],  8, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, c1, d1, e1, a1, b1, ((uint32_t*)data)[15],  5, RIPEMDC[4]);
    RIPEMDSubroundB(RIPEMDJ, b1, c1, d1, e1, a1, ((uint32_t*)data)[13],  6, RIPEMDC[4]);

    RIPEMDSubroundB(RIPEMDF, b2, c2, d2, e2, a2, ((uint32_t*)data)[12],  8, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, a2, b2, c2, d2, e2, ((uint32_t*)data)[15],  5, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, e2, a2, b2, c2, d2, ((uint32_t*)data)[10], 12, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, d2, e2, a2, b2, c2, ((uint32_t*)data)[ 4],  9, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 1], 12, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, b2, c2, d2, e2, a2, ((uint32_t*)data)[ 5],  5, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, a2, b2, c2, d2, e2, ((uint32_t*)data)[ 8], 14, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 7],  6, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, d2, e2, a2, b2, c2, ((uint32_t*)data)[ 6],  8, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 2], 13, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, b2, c2, d2, e2, a2, ((uint32_t*)data)[13],  6, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, a2, b2, c2, d2, e2, ((uint32_t*)data)[14],  5, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, e2, a2, b2, c2, d2, ((uint32_t*)data)[ 0], 15, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, d2, e2, a2, b2, c2, ((uint32_t*)data)[ 3], 13, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, c2, d2, e2, a2, b2, ((uint32_t*)data)[ 9], 11, RIPEMDC[9]);
    RIPEMDSubroundB(RIPEMDF, b2, c2, d2, e2, a2, ((uint32_t*)data)[11], 11, RIPEMDC[9]);

    Math::swap(e1, e2);

    mState[0] += a1;
    mState[1] += b1;
    mState[2] += c1;
    mState[3] += d1;
    mState[4] += e1;
    mState[5] += a2;
    mState[6] += b2;
    mState[7] += c2;
    mState[8] += d2;
    mState[9] += e2;
}

/** virtual function **/
/** finish           **/
//! Finishes the algorithm, no data can be fed again.
/// \return void
/// \param  void
void HashFunctionRIPEMD320_C::finish(void)
{
    uint8_t padding[64];
    uint8_t len[8];
    memset(padding, 0, 64);
    padding[0] = 0x80;

    ((uint32_t*)len)[0] = get_processed() << 3;
    ((uint32_t*)len)[1] = get_processed() >> 29;

    uint32_t buffered = get_processed() & 0x3f;
    uint32_t paddingn = (buffered < 56) ? (56 - buffered) : (120 - buffered);

    feed(padding, paddingn);
    feed(len, 8);
}

/** virtual function **/
/** get_hash         **/
//! Returns the hash.
/// \return void
/// \param   uint8_t *hash
///         A pointer to a location where you want to store the hash.
void HashFunctionRIPEMD320_C::get_hash( uint8_t *hash)
{
    for(uint32_t a = 0; a < 40; a++)
        hash[a] = ((uint8_t*)mState)[a];
}

} // namespace Crypto
} // namespace Myth
